/** Project : Sticky Notes Plus */
/** Author  : Sainagakishore Srikantham */
/** Email   : ssn.kishore@gmail.com */

/** File    : StickyNotesUIMgr.cpp */
/** Purpose : This file contains the definition for the class CStickyNotesUIMgr which is primarily responsible to deal
              with all the UI componens of the project */

#include <QMenu>
#include <QAction>
#include <QSystemTrayIcon>
#include <QMessageBox>
#include <QString>
#include <QApplication>
#include <cstdlib>
#include <vector>

#include "StickyNotesUIMgr.h"
#include "StickyNotesLoginMgr.h"
#include "StickyNote.h"
#include "StickyNotesPlus.h"
#include "StickyNotesDataMgr.h"

using std::vector;

/** Constructor of the class */
CStickyNotesUIMgr::CStickyNotesUIMgr()
{
    /** Creating "actions" */
    iQuitAction = new QAction(tr("&Quit Sticky Notes Plus"), this);
    iShowAllNotes = new QAction(tr("&Show All Notes"), this);
    iHideAllNotes = new QAction(tr("&Hide All Notes"), this);
    iHideAllNotes->setEnabled(false);

    iDonateAction = new QAction(tr("&Donate"), this);

    iAddDateNoteAction = new QAction(tr("&Date Note"), this);
    iAddDayNoteAction = new QAction(tr("Da&y Note"), this);
    iAddGenericNoteAction = new QAction(tr("&Generic Note"), this);
    iPreferencesAction = new QAction(tr("&Preferences"), this);

    /** Creating the system tray context menu */
    iSystemTrayMenu = new QMenu(this);

    iAddNoteMenu = iSystemTrayMenu->addMenu(tr("&Create New Note"));
    iAddNoteMenu->addAction(iAddDateNoteAction);
    iAddNoteMenu->addAction(iAddDayNoteAction);
    iAddNoteMenu->addAction(iAddGenericNoteAction);

    iSystemTrayMenu->addAction(iShowAllNotes);
    iSystemTrayMenu->addAction(iHideAllNotes);
    iSystemTrayMenu->addAction(iPreferencesAction);
    iSystemTrayMenu->addAction(iDonateAction);
    iSystemTrayMenu->addAction(iQuitAction);

    /** Creating the system tray icon */
    iSystemTrayIcon = new QSystemTrayIcon(this);
    iSystemTrayIcon->setToolTip(tr("Sticky Notes Plus\nVersion 0.2.1"));
    iTrayIcon = new QIcon(":/images/stickynote.svg");
    iSystemTrayIcon->setContextMenu(iSystemTrayMenu);
    iSystemTrayIcon->setIcon(*iTrayIcon);
    iSystemTrayIcon->show();
}

/** Destructor of the class */
CStickyNotesUIMgr::~CStickyNotesUIMgr()
{
    /** Actions */
    if(iQuitAction)
    {
        delete iQuitAction;
        iQuitAction = NULL;
    }
    if(iShowAllNotes)
    {
        delete iShowAllNotes;
        iShowAllNotes = NULL;
    }
    if(iHideAllNotes)
    {
        delete iHideAllNotes;
        iHideAllNotes = NULL;
    }
    if(iDonateAction)
    {
        delete iDonateAction;
        iDonateAction = NULL;
    }
    if(iAddDateNoteAction)
    {
        delete iAddDateNoteAction;
        iAddDateNoteAction = NULL;
    }
    if(iAddDayNoteAction)
    {
        delete iAddDayNoteAction;
        iAddDayNoteAction = NULL;
    }
    if(iAddGenericNoteAction)
    {
        delete iAddGenericNoteAction;
        iAddGenericNoteAction = NULL;
    }
    if(iPreferencesAction)
    {
        delete iPreferencesAction;
        iPreferencesAction = NULL;
    }

    /** Menus */
    if(iSystemTrayMenu)
    {
        delete iSystemTrayMenu;
        iSystemTrayMenu = NULL;
    }

    /** Systray Icon */
    if(iSystemTrayIcon)
    {
        delete iSystemTrayIcon;
        iSystemTrayIcon = NULL;
    }

    /** Icon */
    if(iTrayIcon)
    {
        delete iTrayIcon;
        iTrayIcon = NULL;
    }
}

/** Registers the "actions" or signals and slots associated with different UI components */
void CStickyNotesUIMgr::RegisterActions()
{
    /** Actions associated with the systray icon context menu */
    connect(iAddDateNoteAction, SIGNAL(triggered()), this, SLOT(AddDateNoteTriggered()));
    connect(iAddDayNoteAction, SIGNAL(triggered()), this, SLOT(AddDayNoteTriggered()));
    connect(iAddGenericNoteAction, SIGNAL(triggered()), this, SLOT(AddGenericTriggered()));

    connect(iHideAllNotes, SIGNAL(triggered()), this, SLOT(HideAllTriggered()));
    connect(iShowAllNotes, SIGNAL(triggered()), this, SLOT(ShowAllTriggered()));
    connect(iDonateAction, SIGNAL(triggered()), this, SLOT(DonateTriggered()));
    connect(iPreferencesAction, SIGNAL(triggered()), this, SLOT(PreferencesTriggered()));
    connect(iQuitAction, SIGNAL(triggered()), this, SLOT(SaveAndQuit()));

    /** For the Systray Icon */
    connect(iSystemTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
            this, SLOT(IconActivated(QSystemTrayIcon::ActivationReason)));
}

/** Displays a pop up containing the login information of the user */
void CStickyNotesUIMgr::DisplayLoginInfo()
{
    QString loginDuration = CStickyNotesLoginMgr::GetInstance()->GetLoginDuration();
    iSystemTrayIcon->showMessage(tr("Login Information"),
                                 loginDuration, QSystemTrayIcon::Information);
}

/** Overriden function that enables / disables menu items from the systray context menu */
void CStickyNotesUIMgr::setVisible(bool visible)
{
    QDialog::setVisible(visible);
}

/** Called when the user clicks on the systray icon */
void CStickyNotesUIMgr::IconActivated(QSystemTrayIcon::ActivationReason aReason)
{
    static bool flipFlop = false;

    switch (aReason) {
    case QSystemTrayIcon::Trigger:
        DisplayLoginInfo();
    case QSystemTrayIcon::DoubleClick:
        break;
    case QSystemTrayIcon::MiddleClick:
        break;
    default:
        ;
    }
}

/** Called when the 'Hide All Notes' item from the systray context menu is selected */
void CStickyNotesUIMgr::HideAllTriggered()
{
    CStickyNotesDataMgr* dataMgr = CStickyNotesPlus::GetInstance()->GetDataMgr();

    vector<CStickyNote*>::iterator notesBeginIterator = dataMgr->GetNotesBeginIterator();
    vector<CStickyNote*>::iterator notesEndIterator = dataMgr->GetNotesEndIterator();

    while(notesBeginIterator != notesEndIterator)
    {
        (*notesBeginIterator)->hide();
        ++notesBeginIterator;
    }
    iHideAllNotes->setEnabled(false);
    iShowAllNotes->setEnabled(true);
}

/** Called when the 'Show All Notes' item from the systray context menu is selected */
void CStickyNotesUIMgr::ShowAllTriggered()
{
    CStickyNotesDataMgr* dataMgr = CStickyNotesPlus::GetInstance()->GetDataMgr();

    vector<CStickyNote*>::iterator notesBeginIterator = dataMgr->GetNotesBeginIterator();
    vector<CStickyNote*>::iterator notesEndIterator = dataMgr->GetNotesEndIterator();

    if(notesBeginIterator == notesEndIterator)
    {
        QMessageBox::information(0, tr("Sticky Notes Plus"),
                                 tr("You haven't created any notes yet. Get started!"));
        return;
    }

    while(notesBeginIterator != notesEndIterator)
    {
        (*notesBeginIterator)->show();
        ++notesBeginIterator;
    }

    iHideAllNotes->setEnabled(true);
    iShowAllNotes->setEnabled(false);
}

/** Called when the 'Day Note' item from the systray context menu is selected */
void CStickyNotesUIMgr::AddDayNoteTriggered()
{
    // open this later

    /*if(!iHideAllNotes->isEnabled())
        iHideAllNotes->setEnabled(true);*/

    QMessageBox::information(0, tr("Sticky Notes Plus :: Create New Note"),
                             tr("Under Construction!"));
}

/** Called when the 'Date Note' item from the systray context menu is selected */
void CStickyNotesUIMgr::AddDateNoteTriggered()
{
    // open this later

    /*if(!iHideAllNotes->isEnabled())
        iHideAllNotes->setEnabled(true);*/

    QMessageBox::information(0, tr("Sticky Notes Plus :: Create New Note"),
                             tr("Under Construction!"));
}

/** Called when the 'Generic' item from the systray context menu is selected */
void CStickyNotesUIMgr::AddGenericTriggered()
{
    if(!iHideAllNotes->isEnabled())
        iHideAllNotes->setEnabled(true);

    CStickyNotesPlus::GetInstance()->GetDataMgr()->AddNote(STICKY_GENERIC_NOTE);
}

/** Called when the 'Donate' item from the systray context menu is selected */
void CStickyNotesUIMgr::DonateTriggered()
{
    QMessageBox::information(0, tr("Sticky Notes Plus :: Donate"),
                             tr("Thank You for your gesture. We'll be accepting donations soon!"));
}

/** Called when the 'Preferences' item from the systray context menu is selected */
void CStickyNotesUIMgr::PreferencesTriggered()
{
    QMessageBox::information(0, tr("Sticky Notes Plus :: Preferences"),
                             tr("Under Construction!"));
}

/** Called when the 'Quit' item from the systray context menu is selected */
void CStickyNotesUIMgr::SaveAndQuit()
{
    CStickyNotesPlus::GetInstance()->GetDataMgr()->SaveAllNotes();
    exit(EXIT_SUCCESS);
}
